package com.Unidbg_hengdin.ndkdemo;

import com.github.unidbg.Emulator;
import com.github.unidbg.arm.Arm64Svc;
import com.github.unidbg.arm.ArmSvc;
import com.github.unidbg.arm.context.RegisterContext;
import com.github.unidbg.linux.android.dvm.DalvikVM;
import com.github.unidbg.linux.android.dvm.VM;
import com.github.unidbg.memory.SvcMemory;
import com.github.unidbg.pointer.UnidbgPointer;
import com.github.unidbg.virtualmodule.VirtualModule;
import com.sun.jna.Pointer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.Map;

public class Study08  extends VirtualModule<VM>{
    public static final Log log = LogFactory.getLog(Study08.class);

    public Study08(Emulator<?> emulator,VM vm){
        // 创建一个虚拟的 so:  libstudy08.so
        super(emulator, vm,"libstudy08.so");
    }

    @Override
    protected void onInitialize(Emulator<?> emulator, final VM vm, Map<String, UnidbgPointer> symbols) {
        /***
         * 重写 onInitialize 方法
         */
        boolean is64bit = emulator.is64Bit();
        SvcMemory svcMemory = emulator.getSvcMemory();
        // 在符号 map 中，增加  _Z7bEncrypt 和 对应的 encrypt 的绑定关系
        symbols.put("_encrypt",svcMemory.registerSvc(is64bit ? new Arm64Svc() {
            @Override
            public long handle(Emulator<?> emulator) {
                return encrypt(emulator,vm);
            }
        }:new ArmSvc() {
            @Override
            public long handle(Emulator<?> emulator) {
                return encrypt(emulator,vm);
            }
        }));

        symbols.put("_Z7baddFun",svcMemory.registerSvc(is64bit ? new Arm64Svc() {
            @Override
            public long handle(Emulator<?> emulator) {
                return addFun(emulator,vm);
            }
        }:new ArmSvc() {
            @Override
            public long handle(Emulator<?> emulator) {
                return addFun(emulator,vm);
            }
        }));

        symbols.put("_Z7bcheckFun",svcMemory.registerSvc(is64bit? new Arm64Svc() {
            @Override
            public long handle(Emulator<?> emulator) {
                return checkFun(emulator,vm);
            }
        }:new ArmSvc() {
            @Override
            public long handle(Emulator<?> emulator) {
                return checkFun(emulator,vm);
            }
        }));
    }

    public static long encrypt(Emulator<?> emulator, VM vm){
        // 通过 context 获取函数原始参数
        RegisterContext context = emulator.getContext();
        Pointer amgr = context.getPointerArg(0);
        String filename = context.getPointerArg(1).getString(0);
        int mode = context.getIntArg(2);

        // 返回加密结果
        return 0x12345678; // 假设的加密结果
    }

    public long addFun(Emulator<?> emulator, VM vm){
        return 100;
    }

    public long checkFun(Emulator<?> emulator, VM vm){
        return 1;
    }


}
